package com.cloudptt.api.product.func.call.group.fsm.video.recv;

import android.content.Context;

import com.cloudptt.api.comm.CauseCont;
import com.cloudptt.api.comm.CommDlg;
import com.cloudptt.api.models.call.RtcpMsg;
import com.cloudptt.api.product.func.addr.IAddrOp;
import com.cloudptt.api.product.func.call.CallAttr;
import com.cloudptt.api.product.func.call.CallConst;
import com.cloudptt.api.product.func.call.CallTimer;
import com.cloudptt.api.product.func.call.group.GroupCallRecvListener;
import com.cloudptt.api.product.func.call.group.fsm.video.IGroupVideoMemberUpdate;
import com.cloudptt.api.product.func.call.group.fsm.video.IVideoSubState;
import com.cloudptt.api.product.func.call.group.fsm.video.GroupCallMemberInfo;
import com.cloudptt.api.product.log.Log;
import com.cloudptt.api.product.operator.CallOperator;
import com.cloudptt.api.product.res.Resource;
import com.mcptt.db.model.AddrInfo;
import com.mcptt.db.model.GroupMembInfo;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

public class VideoRecvAgent implements IVideoSubState
{
	public final static String Log_Key = "VideoRecvAgent";
	private IVideoSubState currentState = null;
	private GroupCallRecvListener listener = null;
	private Context ctx = null;
	private CallOperator operator = null;
	private IAddrOp addOp = null;
	private String curCallKey = null;
	private String callIdStr = CallAttr.DEF_CALL_ID_STR;
	private String jsonStr = null;
	//	private IRollback rollback = null;
	private CallTimer callTimer = null;

//	private AddrInfo videoUserInfo = null;
//	private GroupCallMemberInfo info= new GroupCallMemberInfo();
	private IGroupVideoMemberUpdate memberUpdate = null;

	public VideoRecvAgent(Context ctx, String curCallKey, String callIdStr, CallOperator operator, IAddrOp addOp, CallTimer callTimer, IGroupVideoMemberUpdate memberUpdate)
	{
		Log.d(VideoRecvAgent.Log_Key, "VideoRecvAgent");
		this.ctx = ctx;
		this.curCallKey = curCallKey;
		this.callIdStr = callIdStr;
		this.operator = operator;
		this.addOp = addOp;
		this.callTimer = callTimer;
		this.memberUpdate= memberUpdate;
		this.currentState = new VideoRecvNoPermissionState(this,true);
	}

	public void setListener(GroupCallRecvListener listener)
	{
		Log.debug(this.getClass(), "setListener listener = " + listener);
		this.listener = listener;
	}

	public void goToState(int nextState){
		IVideoSubState videoState = null;
		Log.d(VideoRecvAgent.Log_Key, "goToState:["+ CallConst.stateTag(this.currentState.getState()) +
				" to "+ CallConst.stateTag(nextState) + "]");

		switch (nextState) {
			case CallConst.VideoRecvState_NoPermission:
				videoState = new VideoRecvNoPermissionState(this,false);
				break;
			case CallConst.VideoRecvState_PendingRequest:
				videoState = new VideoRecvPendingRequestState(ctx,this,jsonStr);
				break;
			case CallConst.VideoRecvState_Permission:
				videoState = new VideoRecvPermissionState(this);
				break;
			case CallConst.VideoRecvState_PendingRelease:
				videoState = new VideoRecvPendingReleaseState(ctx,this,jsonStr);
				break;
			default:
				Log.e(VideoRecvAgent.Log_Key, "Illegal state="+ nextState);
				return;//!!!
		}
		this.setCurrentState(videoState);
	}

	private void setCurrentState(IVideoSubState currentState)
	{
		Log.e(VideoRecvAgent.Log_Key, "setCurrentState currentState= " + CallConst.stateTag(this.currentState.getState()));
		this.currentState.destory();
		this.currentState = currentState;
		if(listener != null )
		{
			listener.updateRecvState(curCallKey,currentState.getState());
		}
	}
	public void notifyRecvUserInfo(String num,String jsonStr)
	{
		Log.e(VideoRecvAgent.Log_Key, "notifyTransUserInfo num="+ num + " jsonStr = " + jsonStr + " listener = " + listener);
		if(num != null
				&& !num.equals(""))
		{
			Log.e(VideoRecvAgent.Log_Key, "notifyTransUserInfo num="+ num + " 1" );
			AddrInfo videoUserInfo = addOp.getUserInfoByNum(num);
			GroupMembInfo memberInfo = videoUserInfo.toGroupCallMemberInfo("");
			GroupCallMemberInfo info= new GroupCallMemberInfo(memberInfo,jsonStr);
			info.updateRecv(true);
			memberUpdate.updateGroupCallMemberInfo(IGroupVideoMemberUpdate.Type_Recv,info);
		}
		sendKeyFrame();
	}

	public void notifyRecvEndUserInfo(String num,String jsonStr)
	{
		Log.e(VideoRecvAgent.Log_Key, "notifyTransUserInfo num="+ num + " jsonStr = " + jsonStr + " listener = " + listener);
		if(num != null
				&& !num.equals(""))
		{
			Log.e(VideoRecvAgent.Log_Key, "notifyTransUserInfo num="+ num + " 1" );
			AddrInfo videoUserInfo = addOp.getUserInfoByNum(num);
			GroupMembInfo memberInfo = videoUserInfo.toGroupCallMemberInfo("");
			GroupCallMemberInfo info= new GroupCallMemberInfo(memberInfo,jsonStr);
			info.updateRecv(false);
			memberUpdate.updateGroupCallMemberInfo(IGroupVideoMemberUpdate.Type_Recv,info);
//			if(listener != null) {
//				listener.notifyRecvEndUserInfo(curCallKey, info);
//			}
		}
//		else
//		{
//			Log.e(VideoRecvAgent.Log_Key, "notifyTransUserInfo num="+ num + " 2" );
//			GroupCallMemberInfo info= new GroupCallMemberInfo();
//			info.update(null,"");
//			if(listener != null) {
//				listener.notifyRecvEndUserInfo(curCallKey, info);
//			}
//		}
	}



//	public void updateVideoPermissionNum(String num)
//	{
//		if(listener != null
//				&& num != null)
//		{
//			if(num.equals(""))
//			{
//				listener.updateRecvPermissionInfo(curCallKey,null);
//				videoUserInfo = null;
//			}
//			else
//			{
//				videoUserInfo = addOp.getUserInfoByNum(num);
//				listener.updateRecvPermissionInfo(curCallKey,videoUserInfo);
//			}
//		}
//	}
	//	public void notifyCurrentState()
//	{
////		this.currentState.destory();
////		this.currentState = currentState;
//		int state = currentState.getState();
//		if(listener != null)
//		{
//			String name = this.currentState.getSpeakName();
//			listener.updateVideoState(state, name);
//		}
//	}
	public int doUserAction(int btnAction)
	{
		return CauseCont.OperateErr_NoAgent;
	}
	public int doUserAction(int btnAction,String jsonStr)
	{
		Log.d( VideoRecvAgent.Log_Key,
				CallConst.stateTag(this.currentState.getState()) + " doUserAction = " + CallConst.userActionTag( btnAction ) + " jsonStr = " + jsonStr);
		this.jsonStr = jsonStr;
		return this.currentState.doUserAction(btnAction,jsonStr);
	}

	public void updateTime(CallTimer timer) {
		this.callTimer.updateTime(timer);
	}


	public void receiveRtcpMsg(RtcpMsg msg)
	{
		Log.d(VideoRecvAgent.Log_Key, CallConst.stateTag(this.currentState.getState()) +" receiveRtcpMsg msg = " + msg);
		this.currentState.receiveRtcpMsg(msg);
	}
	public int getState()
	{
		return this.currentState.getState();
	}

	@Override
	public void destory() {
		// TODO Auto-generated method stub
		this.currentState.destory();
	}
	protected int sendTrans(int type,String userId,long audioSsrc,long videoSsrc)
	{
		Log.d(VideoRecvAgent.Log_Key, CallConst.stateTag(this.currentState.getState()) +" sendTrans type = " + type +  " userId = " + userId + " audioSsrc = " + audioSsrc + " videoSsrc = " + videoSsrc);
		Context ctx = this.getCtx();
		if(null == operator
				|| null == ctx)
		{
			return CauseCont.OperateErr_SIP;
		}
		int result = operator.sendTransMsg(callIdStr,type,userId,audioSsrc,videoSsrc);
		if( CauseCont.OperateCheck_Suc != result ) {
			result = CauseCont.OperateErr_SIP;
		}
		return result;
	}

	protected int sendRecv(int type,String userId,long audioSsrc,long videoSsrc)
	{
		Log.d(VideoRecvAgent.Log_Key, CallConst.stateTag(this.currentState.getState()) +" sendRecv type = " + type +  " userId = " + userId + " audioSsrc = " + audioSsrc + " videoSsrc = " + videoSsrc);
		Context ctx = this.getCtx();
		if(null == operator
				|| null == ctx)
		{
			return CauseCont.OperateErr_SIP;
		}
		int result = operator.sendRecvMsg(callIdStr,type,userId,audioSsrc,videoSsrc);
		if( CauseCont.OperateCheck_Suc != result ) {
			result = CauseCont.OperateErr_SIP;
		}
		return result;
	}

//	protected void opAudioMedia(int opType)
//	{
//		Log.d(VideoRecvAgent.Log_Key, CallConst.stateTag(this.currentState.getState()) +" opAudioMedia opType = " + opType);
//		Context ctx = this.getCtx();
//		if(null == operator
//				|| null == ctx)
//		{
//			String errStr =  Resource.getString("operator_null");//ctx.getString(R.string.operator_null);
//			CommDlg.showToast(ctx,errStr);
//			return;
//		}
//
//		int result = operator.opAudioMedia(callIdStr,opType);
//		if(result != CauseCont.OperateCheck_Suc)
//		{
//			String errStr = CauseCont.getOperateCheckErrStr(result,ctx);
//			CommDlg.showToast(ctx,errStr);
//			return;
//		}
//	}

	protected void sendKeyFrame()
	{
		Log.d(VideoRecvAgent.Log_Key, CallConst.stateTag(this.currentState.getState()) +" sendKeyFrame ");
		Context ctx = this.getCtx();
		if(null == operator
				|| null == ctx)
		{
			String errStr =  Resource.getString("operator_null");//ctx.getString(R.string.operator_null);
			CommDlg.showToast(ctx,errStr);
			return;
		}

		int result = operator.sendKeyFrame(callIdStr);
		if(result != CauseCont.OperateCheck_Suc)
		{
			String errStr = CauseCont.getOperateCheckErrStr(result,ctx);
			CommDlg.showToast(ctx,errStr);
			return;
		}
	}

	protected void opVideoRemoteWinShow(boolean isShow)
	{
		if(currentState != null)
		{
			Log.d(VideoRecvAgent.Log_Key, CallConst.stateTag(this.currentState.getState()) +" opVideoRemoteWinShow isShow = " + isShow);
		}
		else
		{
			Log.d(VideoRecvAgent.Log_Key, "opVideoRemoteWinShow isShow = " + isShow);
		}
		Context ctx = this.getCtx();
		if(null == operator
				|| null == ctx)
		{
			String errStr =  Resource.getString("operator_null");//ctx.getString(R.string.operator_null);
			CommDlg.showToast(ctx,errStr);
			return;
		}

		int result = operator.opVideoWinShow(callIdStr,false,isShow);
		if(result != CauseCont.OperateCheck_Suc)
		{
			String errStr = CauseCont.getOperateCheckErrStr(result,ctx);
			CommDlg.showToast(ctx,errStr);
			return;
		}
	}

	public Context getCtx() {
		return ctx;
	}

	public CallOperator getOperator() {
		return operator;
	}

	public CallTimer getCallTimer() {
		return callTimer;
	}

	public void clearResource()
	{
		currentState.destory();
		currentState = null;
		listener = null;
		ctx = null;
		operator = null;
	}
}
